home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 3: The Continuation / 17-Bit_The_Continuation_Disc.iso / amigan / amigan 17 / zorklook / zorklook.c < prev    next >
C/C++ Source or Header  |  1994-01-27  |  6KB  |  276 lines

  1. /* Unsqueezes Infocom data files
  2.  * Brian Parker 5/10/85
  3.  * Moved to Amiga 21/6/87
  4.  */
  5.  
  6. #include "stdio.h"
  7.  
  8. /*extern    Enable_Abort;*/
  9.  
  10. void main()
  11. {
  12.     FILE *fopen(),*fp;
  13.     char    a[3];        /* temporary storage array */
  14.     char    file[128];    /* file name */
  15.     char    sector[20];    /* sector to start at */
  16.     char    buf[2048];    /* file buffer */
  17.     char    words[1000];    /* contains key words */
  18.     int    place[100];    /* points to words in array 'words' */
  19.     char    x,uppercase,punct,wordnum,wdflag,last;
  20.     int    i,point,arraypos,e;
  21.     long    isector;
  22.  
  23.     uppercase = 0;
  24.     punct = 0;
  25.     last = 0;
  26.     wordnum = 0;
  27.     wdflag = 0;
  28.     point = 0x40;    /* key words start at 40 hex */
  29.     arraypos = 0;
  30.     place[0]=0;    /* first word always starts at 0 */
  31.  
  32. /*    Enable_Abort=1;*/    /* Turn on CNTRL C checking */
  33.  
  34.     printf("\n        Infocom File Unsqueezer");
  35.     printf("\n        ------- ---- ----------");
  36.     printf("\n\n          Brian Parker 21/6/87");
  37.  
  38.     printf("\n\n\nWhat is the name of the file to print? ");
  39.     gets(file);
  40.     if((fp = fopen(file,"r")) == NULL){
  41.         printf("Couldn't open file.\n");
  42.         exit(1);
  43.     }
  44.     printf("\nWhat position to start at? ");
  45.     gets(sector);
  46.     isector=atoi(sector);
  47.  
  48.  
  49. /* First scan table of common words at file location 40 hex and store these
  50.    words (96 of them) sequentially in array "words".
  51.    A pointer to each word in this array is atored in array "place". */
  52.  
  53.     fread(buf,640,1,fp);
  54.     while(wordnum<96){
  55.         words[arraypos]=((*(buf+point) & 124)>>2) + 91;
  56.         words[arraypos + 1]=(((*(buf + point) & 3)<<3)
  57.             | ((*(buf + point + 1)&224)>>5))+91;
  58.         words[arraypos+2]=(*(buf+point+1)&31)+91;
  59.         arraypos+=3;
  60.         point+=2;
  61.         if(*(buf+point-2)&128)
  62.             place[++wordnum]=arraypos;
  63.     }
  64.  
  65. /* Now work backwards through the words and remove space-filling characters
  66.    at the end of words i.e. char 96 */
  67.     
  68.     for(wordnum=96;wordnum>0;--wordnum){
  69.         for(i=place[wordnum]-1;words[i]==96;--i)
  70.             words[i]=0;
  71.     }
  72.  
  73. /* Now search through words and add punctuation and upper case as needed */
  74.  
  75.     for(wordnum=0;wordnum<96;++wordnum){
  76.         for(i=place[wordnum];i<place[wordnum+1];++i){
  77.             if(uppercase){
  78.                 uppercase=0;
  79.                 words[i]=upcase(words[i]);
  80.             }
  81.             else if(punct){
  82.                 punct=0;
  83.                 words[i]=punc(words[i]);
  84.             }
  85.             else{
  86.                 switch (words[i]){
  87.                 case    91:
  88.                     words[i]=' ';
  89.                     break;
  90.                 case    95:
  91.                     uppercase=1;
  92.                     words[i]=0;    /* 0 = null */
  93.                     break;
  94.                 case    96:
  95.                     punct=1;
  96.                     words[i]=0;
  97.                     break;
  98.                 }
  99.             }
  100.         }
  101.     }
  102.  
  103. /* Main routine starts here */
  104. /* Now that the 96 key words are stored, the file can be unsqueezed */
  105.  
  106.     if(fseek(fp,isector,0)==-1){    /* set R/W pointer as required */
  107.         printf("Too large a value.\n");
  108.         exit(1);
  109.     }
  110.     i=0;
  111.     while((fread(buf,1,2048,fp) != 0)){    /* read in 2K at a time */
  112.         for(;i<2048;i+=2){
  113. /* set 'last' if flag bit set, indicating that this is the end of a word */
  114.             last=*(buf+i)&128;
  115. /* Extract three characters from every 2 bytes */
  116. /* Also add 91 to each value so that most letters correspond to their ASCII
  117.    values */
  118.             *(a)=((*(buf+i) & 124)>>2)+91;
  119.             *(a+1)=(((*(buf+i) & 3)<<3)|((*(buf+i+1)&224)>>5))+91;
  120.             *(a+2)=(*(buf+i+1) & 31)+91;
  121. /* If this is the end of a word, wipe off space-filling characters (char 5) */
  122.             if (last){
  123.                 for (x=2;a[x]==96;--x)
  124.                     a[x]=91;
  125.             }
  126. /* Go through these characters and look for prefix characters etc. */
  127.             for (x=0;x<3;x++){
  128. /* If flag set for key word replacement then type relevant word */
  129.                 if(wdflag){
  130.     for(e=place[32*(wdflag-1)+a[x]-91];e<place[32*(wdflag-1)+a[x]-90];++e)
  131.                         printf("%c",words[e]);
  132.                     wdflag=0;
  133.                 }
  134. /* If uppercase flag set then print in upper case */
  135.                 else if(uppercase){
  136.                     uppercase=0;
  137.                     printf("%c",upcase(a[x]));
  138.                 }
  139. /* punctuation flag set then print corresponding punctuation symbol */
  140.                 else if(punct){
  141.                     punct=0;
  142.                     printf("%c",punc(a[x]));
  143.                 }
  144.                 else     switch (a[x]){
  145. /* If prefix character 1,2 or 3 found then set word flag */
  146.                     case 92:
  147.                         wdflag=1;
  148.                         break;
  149.                     case 93:
  150.                         wdflag=2;
  151.                         break;
  152.                     case 94:
  153.                         wdflag=3;
  154.                         break;
  155. /* If prefix character 5 found then set punctuation flag */
  156.                     case 96:
  157.                         punct=1;
  158.                         break;
  159. /* If prefix character 4 found then set upper case flag */
  160.                     case 95:
  161.                         uppercase=1;
  162.                         break;
  163. /* If space character (char 0) found then print space */
  164.                     case 91:
  165.                         printf(" ");
  166.                         break;
  167. /* Otherwise, just print the character as is */
  168.                     default:
  169.                         printf("%c",a[x]);
  170.                         break;
  171.                     }
  172.             }
  173.         }
  174.         i-=2048;
  175.     }
  176.     printf("\n\n                  <END OF FILE>\n");
  177.     printf("              Press RETURN to exit.\n");
  178.     gets(sector);        /* wait so that window doesn't disappear */
  179.     exit(0);
  180. }
  181.  
  182. punc(c)        /* returns puncuation symbol or digit corresponding to c */
  183. int c;
  184. {
  185.     switch(c){
  186.     case 'a':
  187.         c='<';
  188.         break;
  189.     case 'b':
  190.         c='\n';
  191.         break;
  192.     case 'c':
  193.         c='0';
  194.         break;
  195.     case 'd':
  196.         c='1';
  197.         break;
  198.     case 'e':
  199.         c='2';
  200.         break;
  201.     case 'f':
  202.         c='3';
  203.         break;
  204.     case 'g':
  205.         c='4';
  206.         break;
  207.     case 'h':
  208.         c='5';
  209.         break;
  210.     case 'i':
  211.         c='6';
  212.         break;
  213.     case 'j':
  214.         c='7';
  215.         break;
  216.     case 'k':
  217.         c='8';
  218.         break;
  219.     case 'l':
  220.         c='9';
  221.         break;
  222.     case 'm':
  223.         c='.';
  224.         break;
  225.     case 'n':
  226.         c=',';
  227.         break;
  228.     case 'o':
  229.         c='!';
  230.         break;
  231.     case 'p':
  232.         c='?';
  233.         break;
  234.     case 'q':
  235.         c='_';
  236.         break;
  237.     case 'r':
  238.         c='#';
  239.         break;
  240.     case 's':
  241.         c=96;
  242.         break;
  243.     case 't':
  244.         c=34;
  245.         break;
  246.     case 'u':
  247.         c='/';
  248.         break;
  249.     case 'v':
  250.         c=92;
  251.         break;
  252.     case 'w':
  253.         c='-';
  254.         break;
  255.     case 'x':
  256.         c=':';
  257.         break;
  258.     case 'y':
  259.         c='(';
  260.         break;
  261.     case 'z':
  262.         c=')';
  263.         break;
  264.     }
  265.     return (c);
  266. }
  267.  
  268. upcase(c)        /* converts c to uppercase */
  269. int c;
  270. {
  271.     c-=32;
  272.     return(c);
  273. }
  274.  
  275. /* end of zorklook.c */
  276.